home *** CD-ROM | disk | FTP | other *** search
/ Computer Shopper 242 / Issue 242 - April 2008 - DPCS0408DVD.ISO / Software Money Savers / VirtualDub / Source / VirtualDub-1.7.7-src.7z / src / system / source / int128.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2006-11-05  |  8.3 KB  |  461 lines

  1. //    VirtualDub - Video processing and capture application
  2. //    System library component
  3. //    Copyright (C) 1998-2004 Avery Lee, All Rights Reserved.
  4. //
  5. //    Beginning with 1.6.0, the VirtualDub system library is licensed
  6. //    differently than the remainder of VirtualDub.  This particular file is
  7. //    thus licensed as follows (the "zlib" license):
  8. //
  9. //    This software is provided 'as-is', without any express or implied
  10. //    warranty.  In no event will the authors be held liable for any
  11. //    damages arising from the use of this software.
  12. //
  13. //    Permission is granted to anyone to use this software for any purpose,
  14. //    including commercial applications, and to alter it and redistribute it
  15. //    freely, subject to the following restrictions:
  16. //
  17. //    1.    The origin of this software must not be misrepresented; you must
  18. //        not claim that you wrote the original software. If you use this
  19. //        software in a product, an acknowledgment in the product
  20. //        documentation would be appreciated but is not required.
  21. //    2.    Altered source versions must be plainly marked as such, and must
  22. //        not be misrepresented as being the original software.
  23. //    3.    This notice may not be removed or altered from any source
  24. //        distribution.
  25.  
  26. #include "stdafx.h"
  27. #include <math.h>
  28.  
  29. #include <vd2/system/int128.h>
  30.  
  31. #ifndef _M_AMD64
  32.     void __declspec(naked) __cdecl vdasm_uint128_add(uint64 dst[2], const uint64 x[2], const uint64 y[2]) {
  33.         __asm {
  34.             push    ebx
  35.  
  36.             mov        ebx, [esp+16]
  37.             mov        ecx, [esp+12]
  38.             mov        edx, [esp+8]
  39.  
  40.             mov        eax, [ecx+0]
  41.             add        eax, [ebx+0]
  42.             mov        [edx+0],eax
  43.             mov        eax, [ecx+4]
  44.             adc        eax, [ebx+4]
  45.             mov        [edx+4],eax
  46.             mov        eax, [ecx+8]
  47.             adc        eax, [ebx+8]
  48.             mov        [edx+8],eax
  49.             mov        eax, [ecx+12]
  50.             adc        eax, [ebx+12]
  51.             mov        [edx+12],eax
  52.  
  53.             pop        ebx
  54.             ret
  55.         }
  56.     }
  57.  
  58.     void __declspec(naked) __cdecl vdasm_uint128_sub(uint64 dst[2], const uint64 x[2], const uint64 y[2]) {
  59.         __asm {
  60.             push    ebx
  61.  
  62.             mov        ebx, [esp+16]
  63.             mov        ecx, [esp+12]
  64.             mov        edx, [esp+8]
  65.  
  66.             mov        eax, [ecx+0]
  67.             sub        eax, [ebx+0]
  68.             mov        [edx+0],eax
  69.             mov        eax, [ecx+4]
  70.             sbb        eax, [ebx+4]
  71.             mov        [edx+4],eax
  72.             mov        eax, [ecx+8]
  73.             sbb        eax, [ebx+8]
  74.             mov        [edx+8],eax
  75.             mov        eax, [ecx+12]
  76.             sbb        eax, [ebx+12]
  77.             mov        [edx+12],eax
  78.  
  79.             pop        ebx
  80.             ret
  81.         }
  82.     }
  83.  
  84.     void __declspec(naked) vdint128::setSquare(sint64 v) {
  85.         __asm {
  86.             push    edi
  87.             push    esi
  88.             push    ebx
  89.             mov        eax, [esp+20]
  90.             cdq
  91.             mov        esi, eax
  92.             mov        eax, [esp+16]
  93.             xor        eax, edx
  94.             xor        esi, edx
  95.             sub        eax, edx
  96.             sbb        esi, edx
  97.             mov        ebx, eax
  98.             mul        eax
  99.             mov        [ecx], eax
  100.             mov        edi, edx
  101.             mov        eax, ebx
  102.             mul        esi
  103.             mov        ebx, 0
  104.             add        eax, eax
  105.             adc        edx, edx
  106.             add        eax, edi
  107.             adc        edx, 0
  108.             mov        edi, edx
  109.             adc        ebx, 0
  110.             mov        [ecx+4], eax
  111.             mov        eax, esi
  112.             mul        esi
  113.             add        eax, edi
  114.             adc        edx, ebx
  115.             mov        [ecx+8], eax
  116.             mov        [ecx+12], edx
  117.             pop        ebx
  118.             pop        esi
  119.             pop        edi
  120.             ret        8
  121.         }
  122.     }
  123.  
  124.     const vdint128 __declspec(naked) vdint128::operator<<(int v) const {
  125.         __asm {
  126.             push    ebp
  127.             push    ebx
  128.             push    esi
  129.             push    edi
  130.  
  131.             mov        esi,ecx
  132.             mov        edx,[esp+20]
  133.  
  134.             mov        ecx,[esp+24]
  135.             cmp        ecx,128
  136.             jae        zeroit
  137.  
  138.             mov        eax,[esi+12]
  139.             mov        ebx,[esi+8]
  140.             mov        edi,[esi+4]
  141.             mov        ebp,[esi]
  142.  
  143.     dwordloop:
  144.             cmp        ecx,32
  145.             jb        bits
  146.  
  147.             mov        eax,ebx
  148.             mov        ebx,edi
  149.             mov        edi,ebp
  150.             xor        ebp,ebp
  151.             sub        ecx,32
  152.             jmp        short dwordloop
  153.  
  154.     bits:
  155.             shld    eax,ebx,cl
  156.             shld    ebx,edi,cl
  157.             mov        [edx+12],eax
  158.             mov        [edx+8],ebx
  159.             shld    edi,ebp,cl
  160.  
  161.             shl        ebp,cl
  162.             mov        [edx+4],edi
  163.             mov        [edx],ebp
  164.  
  165.             pop        edi
  166.             pop        esi
  167.             pop        ebx
  168.             pop        ebp
  169.             mov        eax,[esp+4]
  170.             ret        8
  171.  
  172.     zeroit:
  173.             xor        eax,eax
  174.             mov        [edx+0],eax
  175.             mov        [edx+4],eax
  176.             mov        [edx+8],eax
  177.             mov        [edx+12],eax
  178.  
  179.             pop        edi
  180.             pop        esi
  181.             pop        ebx
  182.             pop        ebp
  183.             mov        eax,[esp+4]
  184.             ret        8
  185.         }
  186.     }
  187.  
  188.     const vdint128 __declspec(naked) vdint128::operator>>(int v) const {
  189.         __asm {
  190.             push    ebp
  191.             push    ebx
  192.             push    esi
  193.             push    edi
  194.  
  195.             mov        esi,ecx
  196.             mov        edx,[esp+20]
  197.  
  198.             mov        eax,[esi+12]
  199.             mov        ecx,[esp+24]
  200.             cmp        ecx,127
  201.             jae        clearit
  202.  
  203.             mov        ebx,[esi+8]
  204.             mov        edi,[esi+4]
  205.             mov        ebp,[esi]
  206.  
  207.     dwordloop:
  208.             cmp        ecx,32
  209.             jb        bits
  210.  
  211.             mov        ebp,edi
  212.             mov        edi,ebx
  213.             mov        ebx,eax
  214.             sar        eax,31
  215.             sub        ecx,32
  216.             jmp        short dwordloop
  217.  
  218.     bits:
  219.             shrd    ebp,edi,cl
  220.             shrd    edi,ebx,cl
  221.             mov        [edx],ebp
  222.             mov        [edx+4],edi
  223.             shrd    ebx,eax,cl
  224.  
  225.             sar        eax,cl
  226.             mov        [edx+8],ebx
  227.             mov        [edx+12],eax
  228.  
  229.             pop        edi
  230.             pop        esi
  231.             pop        ebx
  232.             pop        ebp
  233.             mov        eax,[esp+4]
  234.             ret        8
  235.  
  236.     clearit:
  237.             sar        eax, 31
  238.             mov        [edx+0],eax
  239.             mov        [edx+4],eax
  240.             mov        [edx+8],eax
  241.             mov        [edx+12],eax
  242.  
  243.             pop        edi
  244.             pop        esi
  245.             pop        ebx
  246.             pop        ebp
  247.             mov        eax,[esp+4]
  248.             ret        8
  249.         }
  250.     }
  251.  
  252.     const vduint128 __declspec(naked) vduint128::operator<<(int v) const {
  253.         __asm {
  254.             push    ebp
  255.             push    ebx
  256.             push    esi
  257.             push    edi
  258.  
  259.             mov        esi,ecx
  260.             mov        edx,[esp+20]
  261.  
  262.             mov        ecx,[esp+24]
  263.             cmp        ecx,128
  264.             jae        zeroit
  265.  
  266.             mov        eax,[esi+12]
  267.             mov        ebx,[esi+8]
  268.             mov        edi,[esi+4]
  269.             mov        ebp,[esi]
  270.  
  271.     dwordloop:
  272.             cmp        ecx,32
  273.             jb        bits
  274.  
  275.             mov        eax,ebx
  276.             mov        ebx,edi
  277.             mov        edi,ebp
  278.             xor        ebp,ebp
  279.             sub        ecx,32
  280.             jmp        short dwordloop
  281.  
  282.     bits:
  283.             shld    eax,ebx,cl
  284.             shld    ebx,edi,cl
  285.             mov        [edx+12],eax
  286.             mov        [edx+8],ebx
  287.             shld    edi,ebp,cl
  288.  
  289.             shl        ebp,cl
  290.             mov        [edx+4],edi
  291.             mov        [edx],ebp
  292.  
  293.             pop        edi
  294.             pop        esi
  295.             pop        ebx
  296.             pop        ebp
  297.             mov        eax,[esp+4]
  298.             ret        8
  299.  
  300.     zeroit:
  301.             xor        eax,eax
  302.             mov        [edx+0],eax
  303.             mov        [edx+4],eax
  304.             mov        [edx+8],eax
  305.             mov        [edx+12],eax
  306.  
  307.             pop        edi
  308.             pop        esi
  309.             pop        ebx
  310.             pop        ebp
  311.             mov        eax,[esp+4]
  312.             ret        8
  313.         }
  314.     }
  315.  
  316.     const vduint128 __declspec(naked) vduint128::operator>>(int v) const {
  317.         __asm {
  318.             push    ebp
  319.             push    ebx
  320.             push    esi
  321.             push    edi
  322.  
  323.             mov        esi,ecx
  324.             mov        edx,[esp+20]
  325.  
  326.             mov        eax,[esi+12]
  327.             mov        ecx,[esp+24]
  328.             cmp        ecx,127
  329.             jae        clearit
  330.  
  331.             mov        ebx,[esi+8]
  332.             mov        edi,[esi+4]
  333.             mov        ebp,[esi]
  334.  
  335.     dwordloop:
  336.             cmp        ecx,32
  337.             jb        bits
  338.  
  339.             mov        ebp,edi
  340.             mov        edi,ebx
  341.             mov        ebx,eax
  342.             xor        eax,eax
  343.             sub        ecx,32
  344.             jmp        short dwordloop
  345.  
  346.     bits:
  347.             shrd    ebp,edi,cl
  348.             shrd    edi,ebx,cl
  349.             mov        [edx],ebp
  350.             mov        [edx+4],edi
  351.             shrd    ebx,eax,cl
  352.  
  353.             shr        eax,cl
  354.             mov        [edx+8],ebx
  355.             mov        [edx+12],eax
  356.  
  357.             pop        edi
  358.             pop        esi
  359.             pop        ebx
  360.             pop        ebp
  361.             mov        eax,[esp+4]
  362.             ret        8
  363.  
  364.     clearit:
  365.             sar        eax, 31
  366.             mov        [edx+0],eax
  367.             mov        [edx+4],eax
  368.             mov        [edx+8],eax
  369.             mov        [edx+12],eax
  370.  
  371.             pop        edi
  372.             pop        esi
  373.             pop        ebx
  374.             pop        ebp
  375.             mov        eax,[esp+4]
  376.             ret        8
  377.         }
  378.     }
  379. #endif
  380.  
  381. const vdint128 vdint128::operator*(const vdint128& x) const {
  382.     vdint128 X = x.abs();
  383.     vdint128 Y = abs();
  384.  
  385.     vduint128 bd(VDUMul64x64To128(X.q[0], Y.q[0]));
  386.  
  387.     bd.q[1] += X.q[0]*Y.q[1] + X.q[1]*Y.q[0];
  388.  
  389.     return (q[1]^x.q[1])<0 ? -(const vdint128&)bd : (const vdint128&)bd;
  390. }
  391.  
  392. vdint128::operator double() const {
  393.     return (double)(unsigned long)q[0]
  394.         + ldexp((double)(unsigned long)((unsigned __int64)q[0]>>32), 32)
  395.         + ldexp((double)q[1], 64);
  396. }
  397.  
  398. /////////////////////////////////////////////////////////////////////////////
  399.  
  400. const vduint128 vduint128::operator*(const vduint128& x) const {
  401.     vduint128 result(VDUMul64x64To128(q[0], x.q[0]));
  402.  
  403.     result.q[1] += q[0]*x.q[1] + q[1]*x.q[0];
  404.  
  405.     return result;
  406. }
  407.  
  408. #ifdef _M_IX86
  409.     vduint128 __declspec(naked) __cdecl VDUMul64x64To128(uint64 x, uint64 y) {
  410.         __asm {
  411.             mov        ecx,[esp+4]
  412.  
  413.             mov        eax,[esp+8]
  414.             mul        dword ptr [esp+16]        ;EDX:EAX = BD
  415.             mov        [ecx+0],eax
  416.             mov        [ecx+4],edx
  417.  
  418.             mov        eax,[esp+12]
  419.             mul        dword ptr [esp+20]        ;EDX:EAX = AC
  420.             mov        [ecx+8],eax
  421.             mov        [ecx+12],edx
  422.  
  423.             mov        eax,[esp+8]
  424.             mul        dword ptr [esp+20]        ;EDX:EAX = BC
  425.             add        [ecx+4],eax
  426.             adc        [ecx+8],edx
  427.             adc        [ecx+12], 0
  428.  
  429.             mov        eax,[esp+12]
  430.             mul        dword ptr [esp+16]        ;EDX:EAX = AD
  431.             add        [ecx+4],eax
  432.             adc        [ecx+8],edx
  433.             adc        [ecx+12], 0
  434.  
  435.             mov        eax, ecx
  436.             ret
  437.         }
  438.     }
  439. #endif
  440.  
  441. uint64 VDUDiv128x64To64(const vduint128& dividend, uint64 divisor, uint64& remainder) {
  442.     vduint128 temp(dividend);
  443.     vduint128 divisor2(divisor);
  444.  
  445.     divisor2 <<= 63;
  446.  
  447.     uint64 result = 0;
  448.     for(int i=0; i<64; ++i) {
  449.         result += result;
  450.         if (temp >= divisor2) {
  451.             temp -= divisor2;
  452.             ++result;
  453.         }
  454.         temp += temp;
  455.     }
  456.  
  457.     remainder = temp.q[1];
  458.  
  459.     return result;
  460. }
  461.